package com.zh.risk.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.result.DeleteResult;
import com.zh.common.aop.SpecialAop;
import com.zh.risk.controller.CallRiskController;
import com.zh.risk.dao.BlackListDao;
import com.zh.risk.dao.RiskMerchTransDao;
import com.zh.risk.entity.RiskBlackList;
import com.zh.risk.entity.RiskMerchTrans;
import com.zh.risk.entity.RiskModel;
import com.zh.risk.service.RiskMerchTransService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;

import static com.zh.risk.RiskConstants.IP_RISK;

/**
 * code is far away from bug with the animal protecting
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @Description: 商户交易业务风控实现层
 * @Author: Liard
 * @Create in: 2020/7/11 11:18
 * @Version: 1.0.1
 */
@Service
public class RiskMerchTransServiceImpl extends ServiceImpl<RiskMerchTransDao, RiskMerchTrans> implements RiskMerchTransService {

    @Autowired
    private RiskMerchTransDao dao;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private BlackListDao blackListDao;

    @Override
    public IPage<RiskMerchTrans> getRiskMerchTrans(Page<RiskMerchTrans> page, RiskMerchTrans param) {
        return dao.selectPage(page, new LambdaQueryWrapper<RiskMerchTrans>()
                .like(StringUtils.isNotEmpty(param.getCode()), RiskMerchTrans::getCode, param.getCode())
                .like(StringUtils.isNotEmpty(param.getName()), RiskMerchTrans::getName, param.getName())
                .eq(Objects.nonNull(param.getCardType()), RiskMerchTrans::getCardType, param.getCardType())
                .eq(Objects.nonNull(param.getLevel()), RiskMerchTrans::getLevel, param.getLevel())
                .eq(Objects.nonNull(param.getType()), RiskMerchTrans::getType, param.getType())
                .eq(Objects.nonNull(param.getGenre()), RiskMerchTrans::getGenre, param.getGenre())
        );
    }

    @Override
    public boolean addRiskMerchTrans(RiskMerchTrans param) {
        int code = Integer.parseInt(dao.getMaxCode().get("code"));
        param.setCode("A_" + ++code);
        int i = dao.insert(param);
        return i > 0;
    }

    @Override
    public boolean modRiskMerchTrans(RiskMerchTrans param) {
        int i = dao.updateById(param);
        return i > 0;
    }

    @Override
    public boolean delRiskMerchTrans(RiskMerchTrans param) {
        return dao.delete(new LambdaQueryWrapper<RiskMerchTrans>().eq(RiskMerchTrans::getId, param.getId())) > 0;
    }

    @SpecialAop
    @Override
    public boolean getBlackTransList(String param) throws JSONException {
        Query query = new Query();
        HashMap<String,String> hashMap = JSON.parseObject(param, HashMap.class);
        // 通过指定ip查询
        if (StrUtil.isNotEmpty(hashMap.get("ip"))) {
           query.addCriteria(Criteria.where("riskObj").is(hashMap.get("ip")));
        }
        // 查询所有
        return mongoTemplate.find(query, RiskBlackList.class).size() > 0;
    }

    // 风险地区限制
    @SpecialAop
    @Override
    public Map<String,Object> getBlackAreaList(String param) throws JSONException {
        HashMap<String,Object> retMap = new HashMap<>();
        HashMap<String,String> paramMap = JSON.parseObject(param, HashMap.class);
        List<RiskBlackList> list = blackListDao.selectList(new LambdaQueryWrapper<RiskBlackList>().eq(RiskBlackList::getType, "7"));
        if (StringUtils.isEmpty(paramMap.get("areaCode"))) {
            log.warn("商户进件，缺少必要参数areaCode");
            retMap.put("success", false);
            retMap.put("message", "商户进件，缺少必要参数areaCode");
        }
        String areaCode = paramMap.get("areaCode");
        for (RiskBlackList blackList : list) {
            if (blackList.getRiskObj().equals(areaCode)) {
                log.warn("该商户在限制区域，禁止进件!");
                retMap.put("success", false);
                retMap.put("message", "该商户在限制区域，禁止进件!");
                break;
            } else {
                retMap.put("success", true);
                retMap.put("message", "操作完成!");
            }
        }
        return retMap;
    }

    @Override
    public List<RiskModel> getRiskModel(String id, String name) {
        Query query = new Query();
        Criteria criteria = Criteria.where("mrcId").is(id);
        query.addCriteria(criteria);
        if (StrUtil.isNotEmpty(name)) {
            Pattern pattern = Pattern.compile("^.*"+name+".*$", Pattern.CASE_INSENSITIVE);
            Criteria criteria1 = Criteria.where("name").regex(pattern);
            query.addCriteria(criteria1);
        }
        return mongoTemplate.find(query, RiskModel.class);
    }

    @Override
    public RiskModel modRiskModel(RiskModel riskModel) {
        //修改商户交易风控规则的得分
        updateRiskMerchTransScore(riskModel);
        //交易风控模型规则的修改保存
        RiskModel  updateRiskModel =mongoTemplate.save(riskModel, "riskModel");
        return updateRiskModel;
    }

    @Override
    public boolean delRiskModel(String id) {
        Query query = Query.query(Criteria.where("_id").is(id));
        //将商户规则的分数减去，再删除规则模型
        RiskModel riskModels = mongoTemplate.findOne(query, RiskModel.class);
        RiskMerchTrans riskMerchTrans = dao.selectById(riskModels.getMrcId());
        riskMerchTrans.setScore(riskMerchTrans.getScore()-riskModels.getScore());
        dao.updateById(riskMerchTrans);
        return mongoTemplate.remove(query, RiskModel.class).wasAcknowledged();
    }

    @Override
    public RiskModel addRiskModel(String id, RiskModel riskModel) {
        // 规则集加入mongodb
        riskModel.setMrcId(id);
        RiskModel  insertRiskModel=  mongoTemplate.insert(riskModel);
        //修改商户交易风控规则的得分
        addRiskMerchTransScore(Integer.valueOf(insertRiskModel.getMrcId()),insertRiskModel.getScore());
        return insertRiskModel;
    }

    @Override
    public boolean addRiskMerchTransScore(Integer mrcId, Integer score) {
        RiskMerchTrans riskMerchTrans = dao.selectById(mrcId);
        int value =  riskMerchTrans.getScore()+score;
        riskMerchTrans.setScore(value);
        int i = dao.updateById(riskMerchTrans);
        return i>0;
    }

    @Override
    public boolean updateRiskMerchTransScore(RiskModel riskModel) {
        //获取商户交易风控规则
        RiskMerchTrans riskMerchTrans = dao.selectById(riskModel.getMrcId());
        //获取风控模型
        Query query = new Query(Criteria.where("_id").is(riskModel.getId()));
        RiskModel riskModels = mongoTemplate.findOne(query, RiskModel.class);
        //将总分值减去模型之前的分值，再相加新修改的模型分值
        int value =  riskMerchTrans.getScore()-riskModels.getScore()+riskModel.getScore();
        riskMerchTrans.setScore(value);
        int i = dao.updateById(riskMerchTrans);
        return i>0;
    }
}
